#include "smtpmailer.h"
#include <QDebug>
#include <QSslConfiguration>
#include <QHostAddress>

SmtpMailer::SmtpMailer(QObject *parent)
    : QObject(parent)
    , m_socket(new QSslSocket(this))
    , m_timer(new QTimer(this))
    , m_port(465)
    , m_useSSL(true)
    , m_state(Init)
{
    qDebug() << "=== SMTP MAILER CONSTRUCTOR ===";
    qDebug() << "SmtpMailer instance created:" << this;
    qDebug() << "Parent object:" << parent;
    qDebug() << "Socket created:" << m_socket;
    qDebug() << "Timer created:" << m_timer;
    
    connect(m_socket, &QSslSocket::connected, this, &SmtpMailer::onConnected);
    connect(m_socket, &QSslSocket::readyRead, this, &SmtpMailer::onReadyRead);
    connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QSslSocket::errorOccurred),
            this, &SmtpMailer::onError);
    connect(m_socket, &QSslSocket::sslErrors, this, &SmtpMailer::onSslErrors);
    connect(m_socket, &QSslSocket::encrypted, this, &SmtpMailer::onEncrypted);
    
    // 配置SSL设置，适配阿里云企业邮箱
    QSslConfiguration sslConfig = m_socket->sslConfiguration();
    sslConfig.setProtocol(QSsl::TlsV1_2OrLater);
    sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone); // 对于企业邮箱，可能需要关闭证书验证
    m_socket->setSslConfiguration(sslConfig);
    
    m_timer->setSingleShot(true);
    m_timer->setInterval(30000); // 30秒超时
    connect(m_timer, &QTimer::timeout, this, &SmtpMailer::onTimeout);
    
    qDebug() << "SmtpMailer constructor complete";
}

void SmtpMailer::setServerConfig(const QString &host, int port, bool useSSL)
{
    qDebug() << "=== SETTING SERVER CONFIG ===";
    qDebug() << "SmtpMailer instance:" << this;
    qDebug() << "Host:" << host;
    qDebug() << "Port:" << port;
    qDebug() << "Use SSL:" << useSSL;
    
    m_host = host;
    m_port = port;
    m_useSSL = useSSL;
    
    qDebug() << "Server config set successfully";
}

void SmtpMailer::setCredentials(const QString &username, const QString &password)
{
    qDebug() << "=== SETTING CREDENTIALS ===";
    qDebug() << "SmtpMailer instance:" << this;
    qDebug() << "Username:" << username;
    qDebug() << "Password length:" << password.length();
    
    m_username = username;
    m_password = password;
    
    qDebug() << "Credentials set successfully";
}

void SmtpMailer::sendMail(const QString &to, const QString &subject, const QString &body)
{
    qDebug() << "=== SMTP MAILER SEND MAIL START ===";
    qDebug() << "SmtpMailer instance:" << this;
    qDebug() << "Recipient:" << to;
    qDebug() << "Subject:" << subject;
    qDebug() << "Body length:" << body.length();
    
    // 验证配置
    qDebug() << "Configuration validation:";
    qDebug() << "  Host:" << m_host;
    qDebug() << "  Port:" << m_port;
    qDebug() << "  Username:" << m_username;
    qDebug() << "  Password length:" << m_password.length();
    qDebug() << "  Use SSL:" << m_useSSL;
    
    if (m_host.isEmpty() || m_username.isEmpty() || m_password.isEmpty()) {
        qDebug() << "ERROR: SMTP configuration incomplete!";
        qDebug() << "  Host empty:" << m_host.isEmpty();
        qDebug() << "  Username empty:" << m_username.isEmpty();
        qDebug() << "  Password empty:" << m_password.isEmpty();
        emit mailError("SMTP配置不完整");
        return;
    }
    
    // 检查当前状态
    qDebug() << "Current state check:";
    qDebug() << "  Current state:" << m_state;
    qDebug() << "  Socket state:" << m_socket->state();
    
    // 如果已经在发送过程中，不允许重复发送
    if (m_state != Init && m_state != Error && m_state != Finished) {
        qDebug() << "ERROR: Mail sending already in progress!";
        emit mailError("邮件正在发送中，请稍后再试");
        return;
    }
    
    // 设置邮件参数
    qDebug() << "Setting mail parameters...";
    m_to = to;
    m_subject = subject;
    m_body = body;
    m_state = Init;
    m_response.clear();
    qDebug() << "Mail parameters set successfully";
    
    // 确保socket处于断开状态
    qDebug() << "Checking socket connection state...";
    if (m_socket->state() != QAbstractSocket::UnconnectedState) {
        qDebug() << "Socket not disconnected, disconnecting...";
        m_socket->disconnectFromHost();
        bool disconnected = m_socket->waitForDisconnected(1000);
        qDebug() << "Socket disconnection result:" << disconnected;
    } else {
        qDebug() << "Socket already disconnected";
    }
    
    // 启动超时定时器
    qDebug() << "Starting timeout timer...";
    m_timer->start();
    qDebug() << "Timer started with interval:" << m_timer->interval() << "ms";
    
    try {
        qDebug() << "Attempting to connect to SMTP server...";
        if (m_useSSL) {
            qDebug() << "Using SSL connection to" << m_host << ":" << m_port;
            m_socket->connectToHostEncrypted(m_host, m_port);
        } else {
            qDebug() << "Using plain connection to" << m_host << ":" << m_port;
            m_socket->connectToHost(m_host, m_port);
        }
        qDebug() << "Connection attempt initiated";
    } catch (const std::exception& e) {
        qDebug() << "EXCEPTION during connection attempt:" << e.what();
        m_timer->stop();
        emit mailError(QString("连接SMTP服务器时发生异常: %1").arg(e.what()));
    } catch (...) {
        qDebug() << "UNKNOWN EXCEPTION during connection attempt";
        m_timer->stop();
        emit mailError("连接SMTP服务器时发生未知异常");
    }
}

void SmtpMailer::onConnected()
{
    qDebug() << "=== SMTP CONNECTION ESTABLISHED ===";
    qDebug() << "SmtpMailer instance:" << this;
    qDebug() << "Socket state:" << m_socket->state();
    qDebug() << "Current SMTP state:" << m_state;
    qDebug() << "Use SSL:" << m_useSSL;
    
    if (m_useSSL) {
        qDebug() << "Waiting for SSL encryption...";
        // 对于SSL连接，等待加密完成
    } else {
        qDebug() << "Plain connection established, setting state to Connected";
        m_state = Connected;
    }
}

void SmtpMailer::onEncrypted()
{
    qDebug() << "=== SSL ENCRYPTION ESTABLISHED ===";
    qDebug() << "SmtpMailer instance:" << this;
    qDebug() << "SSL protocol:" << m_socket->sslConfiguration().protocol();
    qDebug() << "SSL encryption successful";
    qDebug() << "Setting state to Connected";
    m_state = Connected;
}

void SmtpMailer::onReadyRead()
{
    qDebug() << "=== DATA RECEIVED FROM SMTP SERVER ===";
    qDebug() << "SmtpMailer instance:" << this;
    
    QByteArray data = m_socket->readAll();
    qDebug() << "Raw data received:" << data;
    qDebug() << "Data length:" << data.length();
    
    m_response += QString::fromUtf8(data);
    qDebug() << "Current response buffer:" << m_response;
    qDebug() << "Response ends with CRLF:" << m_response.endsWith("\r\n");
    
    if (m_response.endsWith("\r\n")) {
        qDebug() << "Complete response received, processing...";
        processResponse();
    } else {
        qDebug() << "Incomplete response, waiting for more data...";
    }
}

void SmtpMailer::onError(QAbstractSocket::SocketError error)
{
    qDebug() << "=== SMTP SOCKET ERROR ===";
    qDebug() << "SmtpMailer instance:" << this;
    qDebug() << "Error code:" << error;
    
    QString errorString = m_socket->errorString();
    qDebug() << "Error string:" << errorString;
    qDebug() << "Current SMTP state:" << m_state;
    qDebug() << "Socket state:" << m_socket->state();
    
    // 如果邮件已经发送成功，忽略后续的连接错误
    if (m_state == Finished) {
        qDebug() << "Mail already sent successfully, ignoring connection error";
        m_timer->stop();
        return;
    }
    
    // 防止在错误状态下继续处理响应
    if (m_state == Error) {
        qDebug() << "Already in error state, ignoring additional error";
        return;
    }
    
    // 记录当前状态用于错误报告
    State currentState = m_state;
    qDebug() << "Recording current state before error:" << currentState;
    
    // 设置错误状态
    qDebug() << "Setting state to Error and stopping timer";
    m_state = Error;
    m_timer->stop();
    
    // 根据错误类型和当前状态提供更详细的错误信息
    QString detailedError = QString("连接错误 (状态: %1): %2").arg(currentState).arg(errorString);
    
    // 对于SSL握手失败，提供特殊处理
    if (errorString.contains("Handshake failed") || errorString.contains("internal token")) {
        detailedError = "SSL握手失败，可能是证书或加密协议问题。请检查SMTP服务器SSL配置。原始错误: " + errorString;
        qDebug() << "SSL handshake failure detected";
    }
    
    qDebug() << "Emitting error signal:" << detailedError;
    emit mailError(detailedError);
    
    // 安全断开连接
    if (m_socket->state() != QAbstractSocket::UnconnectedState) {
        qDebug() << "Disconnecting socket...";
        m_socket->disconnectFromHost();
    } else {
        qDebug() << "Socket already disconnected";
    }
    qDebug() << "=== ERROR HANDLING COMPLETE ===";
}

void SmtpMailer::onSslErrors(const QList<QSslError> &errors)
{
    qDebug() << "=== SSL ERRORS DETECTED ===";
    qDebug() << "SmtpMailer instance:" << this;
    qDebug() << "Number of SSL errors:" << errors.size();
    
    // 对于阿里云企业邮箱，可能需要忽略某些SSL错误
    QList<QSslError> ignorableErrors;
    for (const QSslError &error : errors) {
        qDebug() << "SSL Error type:" << error.error() << "Message:" << error.errorString();
        // 忽略自签名证书和主机名不匹配的错误（企业邮箱常见）
        if (error.error() == QSslError::SelfSignedCertificate ||
            error.error() == QSslError::HostNameMismatch ||
            error.error() == QSslError::SelfSignedCertificateInChain ||
            error.error() == QSslError::CertificateUntrusted) {
            qDebug() << "Adding to ignorable errors:" << error.errorString();
            ignorableErrors.append(error);
        } else {
            qDebug() << "Non-ignorable SSL error:" << error.errorString();
        }
    }
    
    if (!ignorableErrors.isEmpty()) {
        qDebug() << "Ignoring" << ignorableErrors.size() << "SSL errors";
        m_socket->ignoreSslErrors(ignorableErrors);
    } else {
        qDebug() << "No ignorable SSL errors found";
    }
    qDebug() << "=== SSL ERROR HANDLING COMPLETE ===";
}

void SmtpMailer::onTimeout()
{
    qDebug() << "=== SMTP TIMEOUT ===";
    qDebug() << "SmtpMailer instance:" << this;
    qDebug() << "Current state:" << m_state;
    qDebug() << "Socket state:" << m_socket->state();
    qDebug() << "Timeout interval:" << m_timer->interval() << "ms";
    
    emit mailError("连接超时");
    qDebug() << "Aborting socket connection...";
    m_socket->abort();
    qDebug() << "Socket aborted";
}

void SmtpMailer::sendCommand(const QString &command)
{
    qDebug() << "=== SENDING SMTP COMMAND ===";
    qDebug() << "SmtpMailer instance:" << this;
    qDebug() << "Command:" << command;
    qDebug() << "Socket state:" << m_socket->state();
    qDebug() << "Current SMTP state:" << m_state;
    
    QByteArray data = (command + "\r\n").toUtf8();
    qDebug() << "Raw data to send:" << data;
    qDebug() << "Data length:" << data.length();
    
    qint64 bytesWritten = m_socket->write(data);
    qDebug() << "Bytes written:" << bytesWritten;
    qDebug() << "Write successful:" << (bytesWritten == data.length());
}

void SmtpMailer::processResponse()
{
    qDebug() << "=== PROCESSING SMTP RESPONSE ===";
    qDebug() << "SmtpMailer instance:" << this;
    qDebug() << "Raw response:" << m_response;
    qDebug() << "Trimmed response:" << m_response.trimmed();
    qDebug() << "Current SMTP state:" << m_state;
    
    QString response = m_response.trimmed();
    m_response.clear();
    
    // 防止在错误状态下继续处理响应
    if (m_state == Error) {
        qDebug() << "Already in error state, ignoring response";
        return;
    }
    
    try {
        qDebug() << "Analyzing response code and state...";
        
        if (response.startsWith("220") && m_state == Connected) {
            qDebug() << "Server greeting received, sending EHLO";
            m_state = EhloSent;
            sendCommand("EHLO " + m_host);
        }
        else if (response.startsWith("250") && m_state == EhloSent) {
            qDebug() << "EHLO accepted, starting authentication";
            m_state = AuthLoginSent;
            sendCommand("AUTH LOGIN");
        }
        else if (response.startsWith("334") && m_state == AuthLoginSent) {
            // 服务器请求用户名
            QString challenge = response.mid(4).trimmed();
            qDebug() << "Username challenge received:" << challenge;
            if (!challenge.isEmpty()) {
                // 解码挑战信息（如果有的话）
                QByteArray decodedChallenge = QByteArray::fromBase64(challenge.toUtf8());
                qDebug() << "Decoded challenge:" << decodedChallenge;
                qDebug() << "Decoded challenge:" << QString::fromUtf8(decodedChallenge);
            }
            qDebug() << "Encoding and sending username...";
            m_state = UsernameSent;
            QString encodedUsername = encodeBase64(m_username);
            qDebug() << "Original username:" << m_username;
            qDebug() << "Encoded username:" << encodedUsername;
            sendCommand(encodedUsername);
        }
        else if (response.startsWith("334") && m_state == UsernameSent) {
            // 服务器请求密码
            QString challenge = response.mid(4).trimmed();
            qDebug() << "Password challenge received:" << challenge;
            if (!challenge.isEmpty()) {
                QByteArray decodedChallenge = QByteArray::fromBase64(challenge.toUtf8());
                qDebug() << "Decoded password challenge:" << QString::fromUtf8(decodedChallenge);
            }
            qDebug() << "Encoding and sending password...";
            m_state = PasswordSent;
            QString encodedPassword = encodeBase64(m_password);
            qDebug() << "Password length:" << m_password.length();
            qDebug() << "Encoded password length:" << encodedPassword.length();
            sendCommand(encodedPassword);
        }
        else if (response.startsWith("235") && m_state == PasswordSent) {
            qDebug() << "Authentication successful, sending MAIL FROM";
            m_state = MailFromSent;
            sendCommand("MAIL FROM:<" + m_username + ">");
        }
        else if (response.startsWith("250") && m_state == MailFromSent) {
            qDebug() << "MAIL FROM accepted, sending RCPT TO";
            m_state = RcptToSent;
            sendCommand("RCPT TO:<" + m_to + ">");
        }
        else if (response.startsWith("250") && m_state == RcptToSent) {
            qDebug() << "RCPT TO accepted, sending DATA command";
            m_state = DataSent;
            sendCommand("DATA");
        }
        else if (response.startsWith("354") && m_state == DataSent) {
            qDebug() << "DATA command accepted, sending mail content";
            m_state = BodySent;
            QString mailContent = QString(
                "From: %1\r\n"
                "To: %2\r\n"
                "Subject: %3\r\n"
                "Content-Type: text/plain; charset=UTF-8\r\n"
                "\r\n"
                "%4\r\n"
                ".\r\n"
            ).arg(m_username, m_to, m_subject, m_body);
            
            qDebug() << "Mail content to send:";
            qDebug() << "Content length:" << mailContent.length();
            qDebug() << "Content preview:" << mailContent.left(200) + "...";
            
            qint64 bytesWritten = m_socket->write(mailContent.toUtf8());
            qDebug() << "Mail content bytes written:" << bytesWritten;
        }
        else if (response.startsWith("250") && m_state == BodySent) {
            qDebug() << "Mail content accepted, sending QUIT and finishing";
            m_state = Finished;
            sendCommand("QUIT");
            m_timer->stop();
            qDebug() << "Emitting mailSent signal";
            emit mailSent();
            
            // 延迟关闭连接，等待QUIT响应
            qDebug() << "Setting up delayed connection close";
            QTimer::singleShot(1000, this, [this]() {
                qDebug() << "Delayed connection close triggered";
                if (m_socket && m_socket->state() != QAbstractSocket::UnconnectedState) {
                    qDebug() << "Disconnecting socket after successful mail send";
                    m_socket->disconnectFromHost();
                } else {
                    qDebug() << "Socket already disconnected or null";
                }
            });
        }
        else if (response.startsWith("221") && m_state == Finished) {
            // QUIT命令的响应，正常关闭连接
            qDebug() << "QUIT response received, closing connection";
            if (m_socket && m_socket->state() != QAbstractSocket::UnconnectedState) {
                qDebug() << "Disconnecting socket after QUIT response";
                m_socket->disconnectFromHost();
            } else {
                qDebug() << "Socket already disconnected or null after QUIT";
            }
        }
        else if (response.startsWith("4") || response.startsWith("5")) {
            qDebug() << "SMTP error response received:" << response;
            m_state = Error;
            m_timer->stop();
            emit mailError("SMTP错误: " + response);
            if (m_socket && m_socket->state() != QAbstractSocket::UnconnectedState) {
                qDebug() << "Disconnecting socket after SMTP error";
                m_socket->disconnectFromHost();
            }
        } else {
            qDebug() << "Unexpected response:" << response << "in state:" << m_state;
        }
    } catch (const std::exception& e) {
        qDebug() << "EXCEPTION in processResponse:" << e.what();
        // 捕获任何异常，防止程序崩溃
        m_state = Error;
        m_timer->stop();
        emit mailError(QString("处理SMTP响应时发生异常: %1").arg(e.what()));
        if (m_socket && m_socket->state() != QAbstractSocket::UnconnectedState) {
            m_socket->disconnectFromHost();
        }
    } catch (...) {
        qDebug() << "UNKNOWN EXCEPTION in processResponse";
        // 捕获任何异常，防止程序崩溃
        m_state = Error;
        m_timer->stop();
        emit mailError("处理SMTP响应时发生未知异常");
        if (m_socket && m_socket->state() != QAbstractSocket::UnconnectedState) {
            m_socket->disconnectFromHost();
        }
    }
    qDebug() << "=== RESPONSE PROCESSING COMPLETE ===";
    qDebug() << "Final state:" << m_state;
}

void SmtpMailer::nextStep()
{
    // 预留方法，用于状态机的下一步处理
}

QString SmtpMailer::encodeBase64(const QString &text)
{
    return QString::fromUtf8(text.toUtf8().toBase64());
}